﻿using System;
using System.Management;
using ClusterAware;
using ClusterAwareAdmin.Properties;
using ClusterAwareProperties;
using ClusterAwareWMI;

namespace ClusterAwareAdmin
{
    /// <summary>
    /// Admin ResourceType Methods Class
    /// </summary>
    public class ResourceTypeAdmin : ResourceTypeMethods
    {
        #region private properties

        private readonly ClusterManagerAdmin _managerclass;

        #endregion

        #region CTOR

        /// <summary>
        /// Create Class NodeMethodsAdmin
        /// </summary>
        /// <param name="managerclass">Instance of ClusterManager class</param>
        public ResourceTypeAdmin(ClusterManagerAdmin managerclass)
            : base(managerclass.ManagerInstance)
        {
            _managerclass = managerclass;
        }

        #endregion

        #region public Methods

        ///<summary>
        /// Create a new Resourcetype
        ///</summary>
        ///<param name="resourcetypeName">The name of the resource type.</param>
        ///<param name="displayname">The display name of the resource type.</param>
        ///<param name="dllname">The fully-qualified name of the resource DLL for the resource type.</param>
        ///<param name="looksAlivePollInterval">The default value (in milliseconds) to be used as the poll interval needed by the new resource type's LooksAlive function.</param>
        ///<param name="isAlivePollInterval">Default value (in milliseconds) to be used as the poll interval needed by the new resource type's IsAlive function.</param>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected, 
        /// Parameter resourcetype name is empty
        /// Parameter displayname is empty
        /// Parameter dllname is empty
        /// Failed WMI method execution
        /// </exception>
        public void Create(string resourcetypeName, string displayname, string dllname, UInt32 looksAlivePollInterval, UInt32 isAlivePollInterval)
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            if (string.IsNullOrEmpty(resourcetypeName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "resourceTypeName"));
            }
            if (string.IsNullOrEmpty(displayname))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "displayname"));
            }
            if (string.IsNullOrEmpty(dllname))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "dllname"));
            }
            try
            {
                var path = new ManagementPath("MSCluster_ResourceType");
                using (var classInstance = new ManagementClass(_managerclass.ScopeManager, path, new ObjectGetOptions()))
                {
                    using (var inParams = classInstance.GetMethodParameters("CreateResourceType"))
                    {
                        inParams["Name"] = resourcetypeName;
                        inParams["DisplayName"] = displayname;
                        inParams["DLLName"] = dllname;
                        inParams["LooksAlivePollInterval"] = looksAlivePollInterval;
                        inParams["IsAlivePollInterval"] = isAlivePollInterval;
                        classInstance.InvokeMethod("CreateResourceType", inParams, null);
                        if (_managerclass.CacheInstances)
                        {
                            _managerclass.Refresh(RefreshOption.ResourceTypes,resourcetypeName);
                        }
                    }
                }
            }
            catch (ManagementException ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "ResourceTypes.Create", ex.Message), ex);
            }
            catch (Exception ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "ResourceTypes.Create", ex.Message), ex);
            }
        }

        ///<summary>
        /// Deletes a resource type.
        ///</summary>
        ///<param name="resourcetypeName">The name of the resource type.</param>
        ///<exception cref="ClusterManagerException">
        /// this method throws exception for the following conditions:
        /// Not Connected, 
        /// Parameter resourcetype name is empty, 
        /// Resourcetype not exist, 
        /// Failed WMI method execution
        /// </exception>
        public void Delete(string resourcetypeName)
        {
            if (!_managerclass.IsConnected)
            {
                throw new ClusterManagerException(Resources.Error_NotConnected);
            }
            if (string.IsNullOrEmpty(resourcetypeName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamEmpty, "resourcetypeName"));
            }
            if (!_managerclass.ResourceTypes.ExistResourceType(resourcetypeName))
            {
                throw new ClusterManagerException(string.Format(Resources.Error_ParamNotExist, "Resourcetype", resourcetypeName));
            }
            try
            {
                var res = new ClusterWmiHelpper().GetNode(resourcetypeName, _managerclass.ScopeManager);
                using (var inParams = res.Instance.GetMethodParameters("DeleteResourceType"))
                {
                    res.Instance.InvokeMethod("DeleteResourceType", inParams, null);
                    if (_managerclass.CacheInstances)
                    {
                        _managerclass.ResourceTypeInstances.Remove(resourcetypeName);
                    }
                }
            }
            catch (ManagementException ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "ResourceTypes.Delete", ex.Message), ex);
            }
            catch (Exception ex)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_MethodExecute, "ResourceTypes.Delete", ex.Message), ex);
            }
        }

        #endregion

    }
}
